package example.demo.cas;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.CountDownLatch;

/**
 * 实现自定义的cas-lock
 */
public class CasLock {

    public void lock() {
        for (; !tryLock(); ) {
            Thread.yield();
        }
    }

    public boolean tryLock() {
        return unsafe.compareAndSwapInt(this, valueOffset, 0, 1);
    }

    public void unlock() {
        value = 0;
    }

    static int sum = 0;

    public static void main(String[] args) throws InterruptedException {

        int count = 500;
        CountDownLatch latch = new CountDownLatch(count);
        CountDownLatch main = new CountDownLatch(count);
        CasLock casLock = new CasLock();
        for (int i = 0; i < count; i++) {
            new Thread(() -> {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                casLock.lock();
                for (int j = 0; j < 100000; j++) {
                    sum++;
                }
                casLock.unlock();
                main.countDown();
            }).start();
            latch.countDown();
        }
        long l = System.currentTimeMillis();
        main.await();
        System.out.println(System.currentTimeMillis() - l);
        System.out.println("计算结果---" + sum);
    }

    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe /*= Unsafe.getUnsafe()*/;
    private static final long valueOffset;

    static {
        try {
            Class<Unsafe> unsafeClass = Unsafe.class;
            Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);
            valueOffset = unsafe.objectFieldOffset
                    (CasLock.class.getDeclaredField("value"));
        } catch (Exception ex) {
            throw new Error(ex);
        }
    }

    private volatile int value;
}
